package core

import (
	"encoding/binary"
	"encoding/json"

	"github.com/Jx2f/ViaGenshin/internal/mapper"
	"github.com/Jx2f/ViaGenshin/pkg/crypto/mt19937"
	"github.com/Jx2f/ViaGenshin/pkg/logger"
)

type GetPlayerTokenReq struct {
	KeyID         uint32 `json:"keyId,omitempty"`
	ClientRandKey string `json:"clientRandKey,omitempty"`
}

func (s *Session) OnGetPlayerTokenReq(from, to mapper.Protocol, data []byte) ([]byte, error) {
	packet := new(GetPlayerTokenReq)
	err := json.Unmarshal(data, &packet)
	if err != nil {
		return data, err
	}
	seed, err := s.keys.ServerKey.DecryptBase64(packet.ClientRandKey)
	if err != nil {
		return data, err
	}
	s.loginRand = binary.BigEndian.Uint64(seed)
	return data, nil
}

type GetPlayerTokenRsp struct {
	Uid           uint32 `json:"uid,omitempty"`
	KeyID         uint32 `json:"keyId,omitempty"`
	ServerRandKey string `json:"serverRandKey,omitempty"`
}

func (s *Session) OnGetPlayerTokenRsp(from, to mapper.Protocol, data []byte) ([]byte, error) {
	packet := new(GetPlayerTokenRsp)
	err := json.Unmarshal(data, &packet)
	if err != nil {
		return data, err
	}
	s.playerUid = packet.Uid
	seed, err := s.keys.ClientKeys[packet.KeyID].DecryptBase64(packet.ServerRandKey)
	if err != nil {
		return data, err
	}
	s.loginKey = mt19937.NewKeyBlock(s.loginRand ^ binary.BigEndian.Uint64(seed))
	return data, nil
}

type ResVersionConfig struct {
	Version          uint32 `json:"version"`
	MD5              string `json:"md5"`
	ReleaseTotalSize string `json:"releaseTotalSize"`
	VersionSuffix    string `json:"versionSuffix"`
	Branch           string `json:"branch"`
}

type PlayerLoginRsp struct {
	ClientDataVersion          uint32            `json:"ClientDataVersion"`
	ClientSilenceDataVersion   uint32            `json:"ClientSilenceDataVersion"`
	ClientVersionSuffix        string            `json:"ClientVersionSuffix"`
	ClientSilenceVersionSuffix string            `json:"ClientSilenceVersionSuffix"`
	ResVersionConfig           *ResVersionConfig `json:"resVersionConfig,omitempty"`
}

func (s *Session) onPlayerLoginRsp(from, to mapper.Protocol, data []byte) ([]byte, error) {
	packet := new(PlayerLoginRsp)

	err := json.Unmarshal(data, &packet)
	if err != nil {
		return data, err
	}

	logger.Debug().Msgf("Before modification: %+v", packet)

	packet.ClientDataVersion = 0
	packet.ClientSilenceDataVersion = 0
	packet.ClientVersionSuffix = ""
	packet.ClientSilenceVersionSuffix = ""
	packet.ResVersionConfig = &ResVersionConfig{
		Version:          0,
		MD5:              ``,
		ReleaseTotalSize: "0",
		VersionSuffix:    "",
		Branch:           "",
	}

	modifiedData, err := json.Marshal(packet)
	if err != nil {
		return data, err
	}

	/*
		err = os.WriteFile("outputmod.json", modifiedData, 0644)
		if err != nil {
			logger.Debug().Msgf("Error writing to file:", err)
			return modifiedData, err
		}
	*/

	logger.Debug().Msgf("After modification: %s", modifiedData)

	return modifiedData, nil
}
